﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Windows.Threading;
using System.Windows;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using System.ComponentModel;
using System.Data;
using System.Collections.ObjectModel;
using Vroom.TableListener.Commands;

namespace Vroom.TableListener.ViewModel
{
	public class MainViewModel :  INotifyPropertyChanged , IDisposable
	{
		#region Props
		
		public event PropertyChangedEventHandler PropertyChanged;

		private bool m_IsBusy;
		public bool IsBusy
		{
			get { return m_IsBusy; }
			set { m_IsBusy = value; OnPropertyChanged("IsBusy"); }
		}

		private string _serverConnString;
		public string ServerConnString
		{
			get { return _serverConnString; }
			set { _serverConnString = value; OnPropertyChanged("ServerConnString"); }
		}


		private ObservableCollection<DataRow> _tableRows;
		public ObservableCollection<DataRow> TableRows
		{
			get	{ return TableRows;	}
			set { _tableRows = value; OnPropertyChanged("TableRows"); }
		}

		#endregion


		#region Commands

		public ICommand StartFetch { get; set; }
		public ICommand StopFetch  { get; set; }

		#endregion


		public MainViewModel()
		{
			//StartFetch = new RelayCommand(StartFetchRows, CanStartFetchRows);
		}

		private bool CanStartFetchRows(object obj)
		{
			if (IsBusy)
				return false;
			else
				return true;
		}


		

		protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpresion)
		{
			var property = (MemberExpression)propertyExpresion.Body;
			VerifyPropertyExpression<T>(propertyExpresion, property);
			this.OnPropertyChanged(property.Member.Name);
		}


		protected void OnPropertyChanged(string propertyName)
		{
			if (this.PropertyChanged != null)
			{
				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}


		protected void SetValue<T>(ref T refValue, T newValue, Expression<Func<T>> propertyExpresion)
		{
			if (!object.Equals(refValue, newValue))
			{
				refValue = newValue;
				this.OnPropertyChanged(propertyExpresion);
			}
		}


		protected void SetValue<T>(ref T refValue, T newValue, Action valueChanged)
		{
			if (!object.Equals(refValue, newValue))
			{
				refValue = newValue;
				valueChanged();
			}
		}


		[Conditional("DEBUG")]
		private void VerifyPropertyExpression<T>(Expression<Func<T>> propertyExpresion, MemberExpression property)
		{
			if (property.Member.GetType().IsAssignableFrom(typeof(PropertyInfo)))
			{
				throw new ArgumentException(string.Format(
					CultureInfo.CurrentCulture,
					"Invalid Property Expression {0}",
					propertyExpresion));
			}

			var instance = property.Expression as ConstantExpression;
			if (instance.Value != this)
			{
				throw new ArgumentException(string.Format(
					CultureInfo.CurrentCulture,
					"Invalid Property Expression {0}",
					propertyExpresion));
			}
		}


		public void Dispose()
		{
			OnDispose();
		}


		protected virtual void OnDispose()
		{
		}

		
	}
}
